<template>
  <div class="learn-container">
    <!-- 顶部导航栏 -->
    <div class="top-nav">
      <div class="nav-content">
        <el-button type="text" @click="$router.push('/home/learning')" class="back-btn" style="margin-right: 16px;">
          <i class="el-icon-arrow-left"></i>
          返回学习中心
        </el-button>
        <el-breadcrumb separator="/">
          <el-breadcrumb-item @click="$router.push('/study-home')">首页</el-breadcrumb-item>
          <el-breadcrumb-item>408知识学习</el-breadcrumb-item>
          <el-breadcrumb-item v-if="currentCourse">{{ currentCourse.name }}</el-breadcrumb-item>
        </el-breadcrumb>

        <div class="nav-actions">
          <el-select v-model="selectedCourseId" placeholder="选择课程" @change="changeCourse">
                        <el-option
              v-for="course in courses"
              :key="course.id"
              :label="course.name"
              :value="course.id">
            </el-option>
          </el-select>
        </div>
      </div>
    </div>

    <div class="main-layout">
      <!-- 左侧知识点导航 -->
      <div class="sidebar">
        <div class="sidebar-header">
          <h3>{{ currentCourse?.name || '选择课程' }}</h3>
          <div class="progress-info">
            <span>学习进度: {{ progressPercentDisplay }}%</span>
            <el-progress 
              :percentage="progressPercentDisplay" 
              :stroke-width="8" 
              :color="progressBarColor" 
              :format="progressFormat"
              :show-text="false"
              class="progress-animated"
            />
            <transition name="progress-tip-fade" mode="out-in">
              <p :key="progressTipKey" class="progress-tip">{{ progressTip }}</p>
            </transition>
          </div>
        </div>

        <div class="knowledge-tree">
          <el-tree :data="knowledgeTree" :props="treeProps" node-key="id" :expand-on-click-node="true"
            :highlight-current="true" :default-expand-all="true" @node-click="selectKnowledge"
            class="knowledge-nav-tree">
            <template #default="{ node, data }">
              <div class="tree-node">
                <i :class="getNodeIcon(data)" class="node-icon"></i>
                <span class="node-label">{{ node.label }}</span>
                <span v-if="data.status === 1 && (!data.children || data.children.length === 0)" class="completed-mark" title="已完成">
      <svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
        <circle cx="9" cy="9" r="8" fill="url(#blueGradient)"/>
        <path d="M5 9.5L8 12.5L13 7.5" stroke="white" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"/>
        <defs>
          <linearGradient id="blueGradient" x1="0" y1="0" x2="18" y2="18" gradientUnits="userSpaceOnUse">
            <stop stop-color="#4f8cff"/>
            <stop offset="1" stop-color="#3a6fd8"/>
          </linearGradient>
        </defs>
      </svg>
    </span>
              </div>
            </template>
          </el-tree>
        </div>
      </div>

      <!-- 右侧内容区域 -->
      <div class="content-area">
        <div v-if="!selectedKnowledge" class="empty-state">
          <div class="empty-icon">
            <i class="el-icon-document"></i>
          </div>
          <h3>选择知识点开始学习</h3>
          <p>从左侧导航中选择一个知识点，查看详细的知识导图和学习内容</p>
        </div>

        <div v-else class="knowledge-content">
          <div class="content-header">
            <h2>{{ selectedKnowledge.label }}</h2>
            <div class="header-actions">
              <el-button type="text" @click="toggleFavorite">
                <i :class="selectedKnowledge.isFavorite ? 'el-icon-star-on' : 'el-icon-star-off'"></i>
                {{ selectedKnowledge.isFavorite ? '已收藏' : '收藏' }}
              </el-button>
              <el-button type="text" @click="markAsCompleted">
                <i class="el-icon-check"></i>
                标记完成
              </el-button>
            </div>
          </div>

          <div ref="mindmapContainer" class="mindmap-container"></div>

          <div class="knowledge-details">
            <VueMarkdownIt :source="selectedKnowledge.content" />
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
import axios from 'axios'
import { ref, reactive, computed, onMounted, watch, nextTick, onUnmounted } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import VueMarkdownIt from 'vue3-markdown-it'
import { useUserStore } from '../../../store/UserStore'

export default {
  name: 'Learn408',
  components: { VueMarkdownIt },
  setup() {
    const userStore = useUserStore()
    const router = useRouter()
    const route = useRoute()

  const selectedCourseId = ref(Number(route.query.courseId) || 1)
    const knowledgeTree = ref([])
    const selectedKnowledge = ref(null)
    const mindmapContainer = ref(null)
    const isLoadingMindmap = ref(false)

    // 进度条相关变量
    const progressPercent = ref(0)
    const progressPercentDisplay = computed(() => {
      return Number(progressPercent.value).toFixed(2)
    })
    const progressTip = ref('')
    const progressTipKey = ref(0)
    const progressBarColor = computed(() => {
      const percent = progressPercent.value
      if (percent >= 100) return '#67C23A'      // 绿色
      if (percent >= 80) return '#21cfa3'       // 青绿色
      if (percent >= 60) return '#E6A23C'       // 橙色
      if (percent >= 40) return '#4A90E2'       // 蓝色
      if (percent > 0) return '#b07cff'         // 紫色
      return '#909399'                          // 灰色
    })
    const progressFormat = (percent) => `${percent}%`

    const courses = reactive([
      { id: 1, name: '数据结构', progress: 65 },
      { id: 2, name: '操作系统', progress: 78 },
      { id: 3, name: '计算机组成原理', progress: 42 },
      { id: 4, name: '计算机网络', progress: 33 },
      
    ])

    const treeProps = {
      children: 'children',
      label: 'label'
    }

    const currentCourse = computed(() =>
      courses.find(c => c.id === selectedCourseId.value)
    )

    const getUserId = () => userStore.userInfo?.userId

    const fixNullChildren = (nodes) => {
      nodes.forEach(n => {
        if (!Array.isArray(n.children)) {
          n.children = []
        } else {
          fixNullChildren(n.children)
        }
      })
    }

    // 批量获取完成状态
    const fetchCompletedStatus = async (treeData, userId) => {
      if (!userId) return
      const flatIds = []
      const flattenTree = (nodes) => {
        nodes.forEach(n => {
          flatIds.push(n.id)
          if (n.children && n.children.length) {
            flattenTree(n.children)
          }
        })
      }
      flattenTree(treeData)
      try {
        const res = await axios.post('/userProgress/batch-status', {
          userId,
          pointIds: flatIds,
          courseId: selectedCourseId.value
        })
        const completedMap = res.data || {}
        const updateTreeStatus = (nodes) => {
          nodes.forEach(n => {
            // 统一用 String(n.id) 作为 key，避免类型不一致导致无法标记完成
            n.status = completedMap[String(n.id)] ? 1 : 0
            if (n.children && n.children.length) updateTreeStatus(n.children)
          })
        }
        updateTreeStatus(treeData)
      } catch (e) {
        console.error('批量获取完成状态失败', e)
      }
    }

    // 获取知识点树并集成完成状态
    const fetchKnowledgeTree = async () => {
      try {
        const userId = getUserId()
        if (!userId) {
          console.error('未获取到用户ID，无法加载知识点树')
          knowledgeTree.value = []
          return
        }
        const res = await axios.get('/api/knowledge/tree', {
          params: { courseId: selectedCourseId.value }
        })
        const data = res.data
        if (Array.isArray(data)) {
          fixNullChildren(data)
          await fetchCompletedStatus(data, userId)
          knowledgeTree.value = data
        } else {
          knowledgeTree.value = []
        }
      } catch (err) {
        console.error('获取知识点树失败', err)
        knowledgeTree.value = []
      }
    }

    const changeCourse = async (courseId) => {
      selectedCourseId.value = courseId
      selectedKnowledge.value = null
      await fetchKnowledgeTree()
    }

    // 加载进度
    const loadProgress = async () => {
      try {
        const userId = getUserId()
        if (!userId) return
        const res = await axios.get('/userProgress/course-progress', {
          params: {
            userId,
            courseId: selectedCourseId.value
          }
        })
        progressPercent.value = res.data.progress || 0
        // 动态提示词
        if (progressPercent.value >= 100) {
          progressTip.value = '🎉 太棒了，你已完成所有学习！'
        } else if (progressPercent.value >= 60) {
          progressTip.value = '👍 很好，你已经掌握了大部分内容！'
        } else if (progressPercent.value > 0) {
          progressTip.value = '继续加油，知识就在前方！'
        } else {
          progressTip.value = '开始学习，解锁更多知识！'
        }
        progressTipKey.value++ // 触发动画
      } catch (e) {
        console.error('加载进度失败', e)
      }
    }

    onMounted(async () => {
      if (route.query.course) {
        selectedCourseId.value = parseInt(route.query.course)
      }
      await fetchKnowledgeTree()
      await loadProgress()
    })

    watch(selectedCourseId, async () => {
      await loadProgress()
    })

    const selectKnowledge = async (data) => {
      if (!data.children || data.children.length === 0) {
        try {
          const res = await axios.get('/api/knowledge/contents', {
            params: { pointId: data.id }
          })
          const contentItem = Array.isArray(res.data) ? res.data[0] : null
          
          let safeContent = '<p>暂无内容</p>';
          if (contentItem && typeof contentItem.content === 'string') {
            if (contentItem.content.trim()) {
              safeContent = contentItem.content.trim();
            }
          }
          
          selectedKnowledge.value = {
            ...data,
            content: safeContent,
            title: contentItem && contentItem.title ? contentItem.title : data.label
          }
        } catch (error) {
          console.error('获取知识点内容失败', error)
          selectedKnowledge.value = {
            ...data,
            content: '<p>加载失败</p>'
          }
        }
      }
    }

    const getNodeIcon = (data) => {
      return data.children && data.children.length
        ? 'el-icon-folder'
        : 'el-icon-document'
    }

    const toggleFavorite = () => {
      if (selectedKnowledge.value) {
        selectedKnowledge.value.isFavorite = !selectedKnowledge.value.isFavorite
      }
    }

    // 标记知识点完成并刷新进度和目录树
    const markAsCompleted = async () => {
      if (!selectedKnowledge.value) return
      try {
        const userId = getUserId()
        if (!userId) return
        await axios.post('/userProgress/complete-point', {
          userId,
          pointId: selectedKnowledge.value.id,
          courseId: selectedCourseId.value
        })
        selectedKnowledge.value.status = 1
        await fetchKnowledgeTree() // 标记完成后刷新目录树
        await loadProgress() // 标记完成后刷新进度
      } catch (e) {
        console.error('标记失败', e)
      }
    }
    
    
function parseHTMLContent(htmlContent, title) {
  console.log('开始解析HTML内容:', htmlContent.substring(0, 200) + '...')
  const tempDiv = document.createElement('div')
  tempDiv.innerHTML = htmlContent

  const nodes = [{
    id: 'root',
    isroot: true,
    topic: title || '知识点'
  }]

  let sectionCount = 0
  let itemCount = 0
  let currentH3Id = null // 当前的h3标题ID
  let currentH4Id = null // 当前的h4标题ID
  let currentH5Id = null // 当前的h5标题ID

  // 获取所有相关元素，按DOM顺序处理
  const allElements = tempDiv.querySelectorAll('h1, h2, h3, h4, h5, h6, p, li')
  
  for (let i = 0; i < allElements.length; i++) {
    const element = allElements[i]
    const tagName = element.tagName.toLowerCase()
    const textContent = extractTextFromElement(element)
    
    if (!textContent) continue

    // 处理标题
    if (tagName.match(/^h[1-6]$/)) {
      const level = parseInt(tagName.substr(1))
      sectionCount++
      const nodeId = `h${level}_${sectionCount}`
      
      let parentId = 'root'
      let nodeStyle = `color: #2c5aa0; font-weight: bold;`
      
      // 根据标题级别确定父节点和样式
      if (level === 1 || level === 2) {
        parentId = 'root'
        nodeStyle = `color: #1a365d; font-weight: bold; font-size: 18px;`
        currentH3Id = null
        currentH4Id = null
        currentH5Id = null
      } else if (level === 3) {
        parentId = 'root'
        nodeStyle = `color: #2c5aa0; font-weight: bold; font-size: 16px;`
        currentH3Id = nodeId
        currentH4Id = null
        currentH5Id = null
      } else if (level === 4) {
        parentId = currentH3Id || 'root'
        nodeStyle = `color: #2d3748; font-weight: bold; font-size: 14px;`
        currentH4Id = nodeId
        currentH5Id = null
      } else if (level === 5) {
        parentId = currentH4Id || currentH3Id || 'root'
        nodeStyle = `color: #4a5568; font-weight: bold; font-size: 13px;`
        currentH5Id = nodeId
      } else {
        parentId = currentH5Id || currentH4Id || currentH3Id || 'root'
        nodeStyle = `color: #718096; font-weight: bold; font-size: 12px;`
      }
      
      nodes.push({
        id: nodeId,
        parentid: parentId,
        topic: textContent,
        style: nodeStyle
      })
      
      console.log(`添加${level}级标题: ${textContent} -> 父节点: ${parentId}`)
    }
    // 处理列表项
    else if (tagName === 'li') {
      itemCount++
      const nodeId = `item_${itemCount}`
      
      // 列表项挂到最近的标题下
      let parentId = currentH5Id || currentH4Id || currentH3Id || 'root'
      
      nodes.push({
        id: nodeId,
        parentid: parentId,
        topic: textContent,
        style: `color: #4a5568; font-size: 13px;`
      })
      console.log(`添加列表项: ${textContent} -> 父节点: ${parentId}`)
    }
    // 处理重要段落（可选）
    else if (tagName === 'p' && textContent.length > 15 && textContent.length < 120) {
      itemCount++
      const nodeId = `para_${itemCount}`
      
      let parentId = currentH5Id || currentH4Id || currentH3Id || 'root'
      
      const displayText = textContent.length > 60 ? 
        textContent.substring(0, 60) + '...' : textContent
      
      nodes.push({
        id: nodeId,
        parent: parentId,
        topic: displayText,
        style: `color: #2d3748; font-size: 12px;`
      })
      console.log(`添加段落: ${displayText} -> 父节点: ${parentId}`)
    }
  }

  console.log(`HTML解析完成，共生成${nodes.length}个节点`)
  console.log('节点层级结构:', nodes.map(n => ({ 
    id: n.id, 
    parent: n.parent, 
    topic: n.topic.length > 20 ? n.topic.substring(0, 20) + '...' : n.topic 
  })))

  if (nodes.length === 1) {
    console.log('HTML解析无效果，回退到智能分析')
    return generateSmartNodes(htmlContent, title)
  }
  
  return {
    meta: { name: 'mind', author: 'auto', version: '1.0' },
    format: 'node_array',
    data: nodes
  }
}


// 保持原有的文本提取函数
function extractTextFromElement(element) {
  const clone = element.cloneNode(true)
  clone.querySelectorAll('script, style').forEach(el => el.remove())
  
  let text = clone.textContent || clone.innerText || ''
  text = text.replace(/\s+/g, ' ').trim()
  
  // 清理各种markdown标记
  text = text.replace(/\*\*(.*?)\*\*/g, '$1')
  text = text.replace(/__(.*?)__/g, '$1')
  text = text.replace(/\*(.*?)\*/g, '$1')
  text = text.replace(/_(.*?)_/g, '$1')
  text = text.replace(/`(.*?)`/g, '$1')
  
  return text
}
    

    // 3. 修改原有的 generateMindDataFromContent 函数，添加HTML处理逻辑
function generateMindDataFromContent(content, title) {
  console.log('开始解析内容:', content.substring(0, 200) + '...')
  
  // 检测是否为HTML内容
  const isHTML = /<[^>]+>/.test(content)
  
  if (isHTML) {
    console.log('检测到HTML内容，使用HTML解析器')
    return parseHTMLContent(content, title)
  }
  
  // 原有的markdown解析逻辑保持不变
  const lines = content.split('\n')
  const nodes = [{
    id: 'root',
    isroot: true,
    topic: title || '知识点'
  }]

  let currentSection = 'root'
  let sectionCount = 0
  let itemCount = 0

  for (let i = 0; i < lines.length; i++) {
    const line = lines[i]
    const trimmed = line.trim()
    
    if (!trimmed) continue

    // 检测标题
    const headingMatch = trimmed.match(/^(#{1,6})\s+(.+)$/)
    if (headingMatch) {
      const level = headingMatch[1].length
      const topic = headingMatch[2].trim()
      
      console.log(`发现${level}级标题: ${topic}`)
      
      if (topic) {
        sectionCount++
        const nodeId = `h${level}_${sectionCount}`
        const parentId = level <= 2 ? 'root' : currentSection
        
        nodes.push({
          id: nodeId,
          parent: parentId,
          topic: topic,
          style: `color: #2c5aa0; font-weight: bold;`
        })
        
        if (level <= 3) {
          currentSection = nodeId
        }
      }
    }
    // 检测列表项
    else if (trimmed.match(/^[-*+]\s+/) || trimmed.match(/^\d+\.\s+/)) {
      let topic = trimmed.replace(/^[-*+]\s+/, '').replace(/^\d+\.\s+/, '').trim()
      // 清理markdown格式
      topic = topic.replace(/\*\*(.*?)\*\*/g, '$1').replace(/__(.*?)__/g, '$1')
      
      if (topic && currentSection) {
        itemCount++
        const nodeId = `item_${itemCount}`
        nodes.push({
          id: nodeId,
          parent: currentSection,
          topic: topic,
          style: `color: #4a5568;`
        })
        console.log(`添加列表项: ${topic}`)
      }
    }
    // 检测重要段落
    else if (trimmed.length > 15 && trimmed.length < 80 && 
             !trimmed.startsWith('<') && 
             !trimmed.startsWith('```') &&
             !trimmed.includes('http') &&
             currentSection !== 'root') {
      itemCount++
      const nodeId = `para_${itemCount}`
      nodes.push({
        id: nodeId,
        parent: currentSection,
        topic: trimmed,
        style: `color: #2d3748;`
      })
      console.log(`添加段落: ${trimmed.substring(0, 30)}...`)
    }
  }

  console.log(`解析完成，共生成${nodes.length}个节点:`, nodes)

  if (nodes.length === 1) {
    console.log('只有根节点，使用智能分析')
    return generateSmartNodes(content, title)
  }

  return {
    meta: { name: 'mind', author: 'auto', version: '1.0' },
    format: 'node_array',
    data: nodes
  }
}


    // 智能分析内容生成节点
    function generateSmartNodes(content, title) {
      const nodes = [{
        id: 'root',
        isroot: true,
        topic: title || '知识点'
      }]

      // 按段落分割
      const paragraphs = content.split(/\n\s*\n/).filter(p => p.trim())

      if (paragraphs.length > 1) {
        paragraphs.forEach((paragraph, index) => {
          const trimmed = paragraph.trim()
          if (trimmed) {
            const sentences = trimmed.split(/[。！？.!?]/).filter(s => s.trim())
            const firstSentence = sentences[0]?.trim()

            if (firstSentence) {
              const nodeTitle = firstSentence.length > 30
                ? firstSentence.substring(0, 30) + '...'
                : firstSentence

              const nodeId = `para_${index + 1}`
              nodes.push({
                id: nodeId,
                parent: 'root',
                topic: nodeTitle
              })

              // 添加子句
              if (sentences.length > 1) {
                sentences.slice(1, 3).forEach((sentence, sIndex) => {
                  const trimmedSentence = sentence.trim()
                  if (trimmedSentence) {
                    const subTitle = trimmedSentence.length > 40
                      ? trimmedSentence.substring(0, 40) + '...'
                      : trimmedSentence
                    nodes.push({
                      id: `${nodeId}_${sIndex + 1}`,
                      parent: nodeId,
                      topic: subTitle
                    })
                  }
                })
              }
            }
          }
        })
      } else {
        // 单段落按句子分割
        const sentences = content.split(/[。！？.!?]/).filter(s => s.trim())
        sentences.slice(0, 6).forEach((sentence, index) => {
          const trimmed = sentence.trim()
          if (trimmed) {
            const nodeTitle = trimmed.length > 50
              ? trimmed.substring(0, 50) + '...'
              : trimmed
            nodes.push({
              id: `sent_${index + 1}`,
              parent: 'root',
              topic: nodeTitle
            })
          }
        })
      }

      // 确保至少有一个子节点
      if (nodes.length === 1) {
        nodes.push({
          id: 'default_content',
          parent: 'root',
          topic: '查看下方详细内容'
        })
      }

      return {
        meta: { name: 'mind', author: 'auto', version: '1.0' },
        format: 'node_array',
        data: nodes
      }
    }

    // 清理jsMind实例
    function cleanupJsMind() {
      if (window.currentJsMind) {
        try {
          window.currentJsMind.remove()
        } catch (e) {
          console.warn('清理jsMind实例失败:', e)
        }
        window.currentJsMind = null
      }
    }

  // 1. 首先检查jsMind版本和配置问题
// 在renderMindmap函数中添加详细的调试信息

async function renderMindmap() {
  if (!selectedKnowledge.value?.id) return

  await nextTick()
  if (!mindmapContainer.value) return

  try {
    isLoadingMindmap.value = true
    cleanupJsMind()
    mindmapContainer.value.innerHTML = '<div style="display: flex; align-items: center; justify-content: center; height: 100%; color: #666;"><div>正在加载思维导图...</div></div>'

    await new Promise(resolve => setTimeout(resolve, 500))

    let processedContent = selectedKnowledge.value.content
    let attempts = 0
    const maxAttempts = 5
    
    while (attempts < maxAttempts) {
      const knowledgeDetailsEl = document.querySelector('.knowledge-details')
      if (knowledgeDetailsEl && knowledgeDetailsEl.innerHTML.trim()) {
        const renderedHTML = knowledgeDetailsEl.innerHTML
        if (renderedHTML.includes('<h') || renderedHTML.includes('<p') || renderedHTML.includes('<li')) {
          processedContent = renderedHTML
          console.log('成功获取到渲染后的 HTML 内容')
          break
        }
      }
      attempts++
      await new Promise(resolve => setTimeout(resolve, 200))
    }

    let mindData = generateMindDataFromContent(processedContent, selectedKnowledge.value.title || selectedKnowledge.value.label)
    
    // 添加详细的数据验证
    console.log('=== 思维导图数据验证 ===')
    console.log('总节点数:', mindData.data.length)
    console.log('根节点:', mindData.data.find(n => n.isroot))
    console.log('子节点数量:', mindData.data.filter(n => !n.isroot).length)
    
    // 验证父子关系
    mindData.data.forEach(node => {
      if (!node.isroot) {
        const parent = mindData.data.find(n => n.id === node.parent)
        if (!parent) {
          console.error('发现孤儿节点:', node)
        } else {
          console.log(`节点 "${node.topic}" 的父节点是 "${parent.topic}"`)
        }
      }
    })

    mindmapContainer.value.innerHTML = ''
    await nextTick()

    // 确保容器有足够大小
    if (mindmapContainer.value.offsetHeight < 200) {
      mindmapContainer.value.style.height = '600px'
      mindmapContainer.value.style.width = '100%'
      mindmapContainer.value.style.minHeight = '600px'
      await new Promise(resolve => setTimeout(resolve, 200))
    }

    // 尝试不同的jsMind配置
    const options = {
      container: mindmapContainer.value,
      editable: false,
      theme: 'primary',
      view: {
        hmargin: 120,
        vmargin: 100,
        line_width: 2,
        line_color: '#558b2f'
      },
      layout: {
        hspace: 30,
        vspace: 20,
        pspace: 13
      }
    }

    console.log('=== 创建jsMind实例 ===')
    console.log('容器尺寸:', {
      width: mindmapContainer.value.offsetWidth,
      height: mindmapContainer.value.offsetHeight
    })
    
    const jm = new window.jsMind(options)
    
    // 显示思维导图前再次验证数据
    console.log('即将显示的数据:', JSON.stringify(mindData, null, 2))
    
    jm.show(mindData)
    window.currentJsMind = jm

    // 渲染后检查DOM结构
    setTimeout(() => {
      const mindmapNodes = mindmapContainer.value.querySelectorAll('.jmnode')
      console.log('=== 渲染结果检查 ===')
      console.log('DOM中的思维导图节点数量:', mindmapNodes.length)
      console.log('可见节点:', Array.from(mindmapNodes).filter(n => n.offsetWidth > 0 && n.offsetHeight > 0).length)
      
      mindmapNodes.forEach((node, index) => {
        const text = node.textContent || node.innerText
        const rect = node.getBoundingClientRect()
        console.log(`节点${index + 1}: "${text}" - 位置:`, {
          visible: rect.width > 0 && rect.height > 0,
          width: rect.width,
          height: rect.height,
          left: rect.left,
          top: rect.top
        })
      })
    }, 1000)

    console.log('思维导图渲染完成')
console.log(window.jsMind)
  } catch (error) {
    console.error('渲染思维导图失败:', error)
    console.error('错误堆栈:', error.stack)
    if (mindmapContainer.value) {
      mindmapContainer.value.innerHTML = `
        <div style="padding: 20px; text-align: center; color: #666; border: 1px dashed #ccc; height: 100%; display: flex; align-items: center; justify-content: center; flex-direction: column;">
          <h4 style="margin: 0 0 10px 0; color: #f56565;">加载失败</h4>
          <p style="margin: 0; font-size: 12px; color: #999;">请刷新页面重试</p>
          <p style="margin: 5px 0 0 0; font-size: 11px; color: #ccc;">错误: ${error.message}</p>
        </div>
      `
    }
  } finally {
    isLoadingMindmap.value = false
  }
}
    // 监听选中知识点变化
    watch(selectedKnowledge, (newVal) => {
      if (newVal?.id) {
        renderMindmap()
      } else {
        cleanupJsMind()
        if (mindmapContainer.value) {
          mindmapContainer.value.innerHTML = `
            <div style="padding: 20px; text-align: center; color: #999; height: 100%; display: flex; align-items: center; justify-content: center;">
              请选择知识点查看思维导图
            </div>
          `
        }
      }
    }, { deep: true })

    // 处理窗口大小变化
    const handleResize = () => {
      if (window.currentJsMind && mindmapContainer.value) {
        try {
          window.currentJsMind.resize()
        } catch (e) {
          console.warn('调整思维导图大小失败:', e)
        }
      }
    }


    onMounted(() => {
      window.addEventListener('resize', handleResize)
      if (selectedKnowledge.value?.id) {
        renderMindmap()
      }
    })

    onUnmounted(() => {
      cleanupJsMind()
      window.removeEventListener('resize', handleResize)
    })

    return {
      selectedCourseId,
      knowledgeTree,
      courses,
      treeProps,
      currentCourse,
      changeCourse,
      selectKnowledge,
      getNodeIcon,
      selectedKnowledge,
      toggleFavorite,
      markAsCompleted,
      mindmapContainer,
      progressPercent,
      progressPercentDisplay,
      progressBarColor,
      progressFormat,
      progressTip,
      progressTipKey,
      loadProgress
    }
  }
}
</script>

<style scoped>
.learn-container {
  display: flex;
  flex-direction: column;
  height: 200vh;
  font-family: 'HarmonyOS Sans', 'Microsoft YaHei', 'PingFang SC', Arial, sans-serif;
  background: #e0e7ff;
  margin-top: -40px;
  width: 120%;
  margin-left: -10%;
  padding: 25px;
}

.top-nav {
  background: rgba(255, 255, 255, 0.95);
  padding: 18px 32px 12px 32px;
  box-shadow: 0 2px 8px rgba(80, 120, 255, 0.06);
  border-bottom: 1.5px solid #e0e7ef;
  border-radius: 18px;
  margin-bottom: 8px;
}

.nav-content {
  width: 100%;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.nav-actions {
  display: flex;
  align-items: center;
  gap: 16px;
}

.main-layout {
  display: flex;
  flex: 1;
  overflow: hidden;
  min-height: 1000px;


}

.sidebar {
  width: 320px;

  background: rgba(255, 255, 255, 0.98);
  border-right: 1.5px solid #e0e7ef;
  display: flex;
  flex-direction: column;
  padding: 28px 18px 18px 18px;
  overflow-y: auto;
  box-shadow: 2px 0 8px rgba(80, 120, 255, 0.03);
  border-radius: 18px;
}

.sidebar-header h3 {
  font-size: 20px;
  font-weight: 600;
  margin-bottom: 12px;
  color: #3a4a6b;
  letter-spacing: 1px;
}

.back-btn {
  color: #4b67d6;
  font-weight: bold;
  font-size: 16px;
  margin-bottom: 0;
  margin-top: 0;
  padding-left: 0;
}
.back-btn .el-icon-arrow-left {
  margin-right: 4px;
  font-size: 18px;
}

.progress-info {
  font-size: 14px;
  color: #6b7280;
  margin-bottom: 8px;
}

.knowledge-tree {
  flex: 1;
  margin-top: 10px;
}

.knowledge-nav-tree {
  background: transparent;
}

.tree-node {
  display: flex;
  align-items: center;
  padding: 4px 0;
  border-radius: 6px;
  transition: background 0.18s;
}

.tree-node:hover {
  background: #f1f5ff;
}

.node-icon {
  margin-right: 8px;
  color: #4f8cff;
  font-size: 18px;
}

.node-label {
  flex: 1;
  font-size: 15px;
  color: #374151;
}

.completed-mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: transparent;
  margin-left: 6px;
  box-shadow: 0 2px 8px #4f8cff22;
  transition: box-shadow 0.18s, transform 0.18s;
  cursor: default;
  vertical-align: middle;
  position: relative;
}
.completed-mark svg {
  display: block;
}
.completed-mark:hover {
  box-shadow: 0 4px 16px #4f8cff44;
  transform: scale(1.12);
}

.content-area {
  display: flex;
  flex-direction: column;
  flex: 1;
  padding: 0px 0px 10px 10px;
  background: transparent;
  min-height: 100vh;
  box-sizing: border-box;
}

.knowledge-content {
  background: rgba(255, 255, 255, 0.98);
  padding: 32px 36px 28px 36px;
  border-radius: 18px;
  box-shadow: 0 4px 24px rgba(80, 120, 255, 0.10), 0 1.5px 6px rgba(80, 120, 255, 0.04);
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  max-height: 100%;
  display: flex;
  flex-direction: column;
  transition: box-shadow 0.2s;
}

.knowledge-content::-webkit-scrollbar {
  width: 8px;
  background: #f3f6fa;
}

.knowledge-content::-webkit-scrollbar-thumb {
  background: #b6c6e6;
  border-radius: 6px;
}

.content-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 22px;
  border-bottom: 1.5px solid #e0e7ef;
  padding-bottom: 10px;
}

.content-header h2 {
  font-size: 26px;
  font-weight: 700;
  color: #2a3a5a;
  letter-spacing: 1px;
  margin: 0;
}

.header-actions el-button,
.header-actions .el-button {
  margin-left: 12px;
  font-size: 15px;
  color: #4f8cff;
  transition: color 0.18s;
}

.header-actions .el-button:hover {
  color: #1d4ed8;
}

/* 思维导图美化：紫色渐变风格、圆角、阴影、节点高亮、线条柔和 */
.mindmap-container {
  width: 100%;
  min-height: 900px;
  border: none;
  background: linear-gradient(120deg, #e0e7ff 60%, #f8f9ff 100%);
  border-radius: 18px;
  margin-bottom: 24px;
  box-shadow: 0 6px 32px 0 rgba(120, 80, 255, 0.10), 0 1.5px 8px rgba(120, 80, 255, 0.06);
  overflow: auto;
  position: relative;
  transition: box-shadow 0.2s, border 0.2s;
}
.mindmap-container:hover {
  box-shadow: 0 12px 36px rgba(120, 80, 255, 0.18);
  border: 1.5px solid #b7aaff;
}

/* 思维导图节点美化升级：知识点内容色彩、点击高亮、立体卡片感、边框渐变、阴影、动画 */
.mindmap-container .jmnode {
  position: absolute;
  border-radius: 18px !important;
  background: linear-gradient(120deg, #fff 0%, #f3eaff 100%) !important;
  color: #6a4cff !important;
  font-weight: 600;
  font-size: 1.13rem;
  box-shadow: 0 6px 24px 0 rgba(120, 80, 255, 0.13), 0 1.5px 8px rgba(120, 80, 255, 0.08);
  border: 2.5px solid transparent !important;
  background-clip: padding-box;
  padding: 12px 28px !important;
  min-width: 80px;
  max-width: 400px;
  text-align: center;
  cursor: pointer;
  letter-spacing: 0.5px;
  transition: box-shadow 0.22s, background 0.22s, color 0.22s, border 0.22s, transform 0.18s;
  filter: drop-shadow(0 2px 8px #b7aaff33);
  /* 卡片立体感 */
  background-blend-mode: lighten;
  /* 渐变边框 */
  border-image: linear-gradient(90deg, #a18fff 0%, #7f6fff 100%) 1;
  /* 节点出现动画 */
  animation: mindmapNodeFadeIn 0.7s cubic-bezier(.4,2,.6,1) both;
}
@keyframes mindmapNodeFadeIn {
  0% { opacity: 0; transform: scale(0.7) translateY(30px); }
  100% { opacity: 1; transform: scale(1) translateY(0); }
}
.mindmap-container .jmnode:hover {
  background: linear-gradient(120deg, #f3eaff 0%, #e0e7ff 100%) !important;
  color: #fff !important;
  box-shadow: 0 12px 36px 0 rgba(120, 80, 255, 0.22);
  border: 2.5px solid #a18fff !important;
  z-index: 2;
  transform: scale(1.07);
}
.mindmap-container .jmnode.selected {
  background: linear-gradient(120deg, #7f6fff 0%, #a18fff 100%) !important;
  color: #fff !important;
  border: 2.5px solid #6a4cff !important;
  box-shadow: 0 16px 48px rgba(120, 80, 255, 0.28);
  z-index: 3;
  transform: scale(1.11);
}
.mindmap-container .jmnode.root {
  background: linear-gradient(120deg, #a18fff 0%, #fff 100%) !important;
  color: #6a4cff !important;
  font-size: 1.25rem;
  font-weight: 800;
  border: 3px solid #7f6fff !important;
  box-shadow: 0 16px 48px rgba(120, 80, 255, 0.22);
  letter-spacing: 1px;
  text-shadow: 0 2px 8px #b7aaff44;
}
.mindmap-container .jmexpander {
  background: #a18fff !important;
  border-radius: 50%;
  width: 20px !important;
  height: 20px !important;
  border: 2px solid #d1c4e9 !important;
  box-shadow: 0 2px 8px rgba(120, 80, 255, 0.10);
  transition: background 0.18s, border 0.18s;
}
.mindmap-container .jmexpander:hover {
  background: #7f6fff !important;
  border-color: #a18fff !important;
}
.mindmap-container .jmline {
  stroke: #a18fff !important;
  stroke-width: 3.5px !important;
  filter: drop-shadow(0 2px 6px #b7aaff33);
  opacity: 0.95;
  transition: stroke 0.18s;
}
/* 响应式适配 */
@media (max-width: 900px) {
  .mindmap-container .jmnode {
    font-size: 1rem;
    padding: 7px 12px !important;
    min-width: 50px;
    max-width: 180px;
  }
}

.knowledge-details {
  flex: 1 1 auto;
  overflow-y: auto;
  min-height: 0;
  font-size: 1.18rem;
  line-height: 1.85;
  padding: 24px 18px 0 8px;
  background: transparent;
  border-radius: 10px;
  color: #2a3a5a;
  margin-top: 10px;
}

.knowledge-details::-webkit-scrollbar {
  width: 7px;
  background: #f3f6fa;
}

.knowledge-details::-webkit-scrollbar-thumb {
  background: #b6c6e6;
  border-radius: 6px;
}

.empty-state {
  text-align: center;
  color: #909399;
  margin-top: 100px;
}

.empty-icon {
  font-size: 54px;
  color: #b6c6e6;
  margin-bottom: 18px;
}

@media (max-width: 1200px) {
  .content-area {
    padding: 16px 4vw 16px 4vw;
  }

  .knowledge-content {
    padding: 18px 8px 16px 8px;
  }
}

@media (max-width: 900px) {
  .main-layout {
    flex-direction: column;
  }

  .sidebar {
    width: 100%;
    border-right: none;
    border-bottom: 1.5px solid #e0e7ef;
    box-shadow: none;
    padding: 12px 8px 8px 8px;
  }

  .content-area {
    padding: 8px 2vw 8px 2vw;
  }

  .knowledge-content {
    padding: 10px 2px 8px 2px;
    border-radius: 10px;
  }

  .mindmap-container {
    height: 260px;
    border-radius: 8px;
  }
}

/* 新增样式：进度条提示文本淡入淡出动画 */
.progress-tip {
  font-size: 15px;
  color: #4A90E2;
  margin-top: 6px;
  font-weight: 600;
  letter-spacing: 1px;
  min-height: 24px;
  transition: color 0.3s;
}

.progress-tip-fade-enter-active, .progress-tip-fade-leave-active {
  transition: opacity 0.5s;
}
.progress-tip-fade-enter-from, .progress-tip-fade-leave-to {
  opacity: 0;
}
.progress-tip-fade-enter-to, .progress-tip-fade-leave-from {
  opacity: 1;
}

.progress-animated {
  transition: width 0.7s cubic-bezier(.4,2,.6,1), background 0.3s, box-shadow 0.3s;
  box-shadow: 0 2px 12px #b7aaff33;
}
</style>
